<template>
  <div class="h-[100%] w-[100%] mapbox">
    <div class="h-[175px] w-[35px] z-1000 btnbox">
      <div class="btn" v-for="item in typeList" :key="item" @click="mapdraw(item.type)">
        {{ item.type }}
      </div>
      <div class="btn" @click="stopDraw()">
        <el-icon :size="25" class="mt-[5px]">
          <Brush />
        </el-icon>
      </div>
    </div>
    <div :id="props.id" class="map" ref="mapDraw" :style="{ zoom }"></div>
  </div>
</template>

<script setup lang="ts">
// 地图库
import L from "leaflet";
import "leaflet/dist/leaflet.css";
// 绘制地图空间
import "leaflet-draw";
import "leaflet-draw/dist/leaflet.draw.css";
import "./map/leaflet.draw-cn.js";

import { onMounted, nextTick, onUnmounted, ref } from "vue";
import { BaseLayer } from "./map/BaseLayler.js";
import markerIcon from "@/assets/img/map/marker-icon.png";

let map: any;
let zoom = ref(1); // 地图显示区域的缩放比例
let typeList = [ // 绘制工具
  {
    type: "点",
  },
  {
    type: "线",
  },
  {
    type: "面",
  },
  // {
  //   type: "圆",
  // },
];
let drawControl: any; // 绘制工具
let drawLayerGrounp: any; // 绘制的图层组对象
let drawObj: any; // 绘制种类
let baseLayerMap: any = [];
let markerItem = {};

let props = defineProps({
  id: { // 初始化地图
    type: String,
    default: "map",
  },
  isDraw: { // 是否展示绘制地图
    type: Boolean,
    default: true,
  },
  currentLayerIndex: {// 使用哪个图层
    type: Number,
    default: 1,
  },
});
let emit = defineEmits([
  "geojson-group",
  "marker-click",
  "setMarkerPoint",
  'mapZoomChange',
]);

// 初始化地图
const initMap = () => {
  const { normalm, normala, imgm, imgm2, imga, imga2 } = BaseLayer; // 获取瓦片组
  // 设置瓦片图层组
  baseLayerMap = [
    new L.layerGroup([imgm, imga]),
    new L.layerGroup([imgm2]),
    new L.layerGroup([normalm, normala]),
  ];
  const layers = baseLayerMap[props.currentLayerIndex == 1 ? 1 : 0]; // 使用瓦片图层

  // map(one，two)创建地图实例，oneHTMl元素id,two地图配置;返回的一个对图各种操作和设置的功能的对象
  map = L.map(props.id, {
    center: [28.653107738, 121.257499459], // 初始地图展示所在的中心点
    zoom: 9, //初始缩放等级
    maxZoom: 16, //最大缩放等级
    minZoom: 8, //最小缩放等级
    zoomControl: false, //不显示缩放小控件
    attributionControl: false, // 不显示版权控件
    layers: [layers], // 基础瓦片的图层
    crs: L.CRS.EPSG4326,
  });
  console.log(map, '地图实例');

  //定义一个地图缩放控件
  // var zoomControl = L.control.zoom({ position: "bottomleft" });

  //将地图缩放控件加载到地图
  // map.addControl(zoomControl);

  // 绘制工具
  if (props.isDraw) {
    // 创建图层并添加到地图中
    var drawnItems = new L.FeatureGroup();
    map.addLayer(drawnItems);

    // L.Control.Draw(options)创建绘制控件，
    drawControl = new L.Control.Draw({
      position: "topright", // 控件的位置，默认是 'topleft'
      draw: { // 工具显示
        polyline: true, // 折线
        polygon: true, // 多边形
        rectangle: false, // 矩形
        circle: true, // 圆形
        marker: { //标记
          icon: L.icon({
            iconUrl: markerIcon,  // 点图标的URL
            iconSize: [17, 22],   // 图标大小
            iconAnchor: [17, 22]  // 图标锚点
          }),
          repeatMode: true, // 绘制完毕后不取消当前绘制工具
        },
        // circlemarker: false, // 圆圈标记（无填充）。
      },
      // edit: {
      //   featureGroup: editableLayers, // 可编辑的图层组
      //   remove: true // 允许移除图层
      // },
    });
    // map.addControl(drawControl); // 绘制空间添加到地图上
    // 给地图添加Leaflet.draw绘制事件，并触发drawCreatedBack
    map.on(L.Draw.Event.CREATED, drawCreatedBack);
  }

  // 给地图添加缩放事件
  map.on('zoomend', () => {
    // map.getZoom() < 12 点位聚合
    // map.getZoom() > 12 不聚合
    emit('mapZoomChange', map.getZoom()) // 地图缩放触发父组件行为并将地图当前的缩放级别和范围数据传递
  })
};

// 交互绘制回调
const drawCreatedBack = (e: any) => {
  let drawLayer = e.layer; // 绘制的图形图层对象
  drawLayerGrounpAddLayer(drawLayer);
};

// 更新绘制的图层组
const drawLayerGrounpAddLayer = (layer: any) => {
  // 没有绘制的图层组时创建一个新的图层组并添加到map；
  if (!drawLayerGrounp) {
    drawLayerGrounp = new L.FeatureGroup(); //图层组
    map.addLayer(drawLayerGrounp); // 添加
  }

  drawLayerGrounp.addLayer(layer); // 将绘制的图层添加到图层组中
};

// 地图工具-绘制
const mapdraw = (type: string) => {
  console.log(type);
  // 如果已经绘制过的
  if (drawObj) {
    drawObj.disable(); //取消当前绘制状态
  }
  switch (type) {
    case "点": {
      drawObj = new L.Draw.Marker(map, drawControl.options.draw.marker);
      break;
    }
    case "线": {
      drawObj = new L.Draw.Polyline(map, drawControl.options.draw.polyline);
      break;
    }
    case "面": {
      drawObj = new L.Draw.Polygon(map, drawControl.options.draw.polygon);
      break;
    }
    // case "圆": {
    //   drawObj = new L.Draw.Circle(map, drawControl.options.draw.circle);
    //   break;
    // }
  }
  drawObj.enable(); // 启用当前绘制状态绘制
};

// 地图工具-删除
const stopDraw = () => {
  console.log(markerItem, "markerItem");
  // 删除初始进入时所有绘制
  Object.keys(markerItem).length &&
    Object.keys(markerItem).forEach((v, i) => {
      console.log(v, "删除所有绘制");
      map.removeLayer(markerItem[v]);
    });
  stopDelDraw(); // 删除所有绘制图层
  drawObj.disable(); // 取消当前绘制状态
};

// 删除所有绘制图层
const stopDelDraw = () => {
  console.log('drawLayerGrounp', drawLayerGrounp);
  // 若存在直接删除全部图层
  if (drawLayerGrounp) {
    drawLayerGrounp.clearLayers();
  }
};


// 绘制geoJSON
const mapdrawsurface = (data: any, color: any, text: any, img: any, flyToBounds: boolean = true) => {
  // 标记配置
  var customIcon = L.divIcon({
    html: `<div style='width:22px;height:22px'><img src='${img || markerIcon
      }' style='width:22px;height:22px;'></img></div>`,
    iconSize: [17, 22],
    iconAnchor: [8, 11],
  });
  // 绘制geoJSON
  let group = L.geoJSON(data, {
    pointToLayer: function (feature, latlng) {
      if (latlng) {
        var marker = L.marker(latlng, { icon: customIcon });
        return marker;
      }
    },
    onEachFeature: function (feature, layer) {
      // 在每个要素上执行操作
      if (feature.properties) {
        // 例如，添加点击事件监听器和绑定弹出窗口
        layer.on("click", function (e) {
          feature.typeLabel = data.name;
          console.log(feature, "feature");

          emit("marker-click", feature); // 在这里处理点击事件
        });
        layer.bindPopup(feature.properties.name).openPopup();
      }
    },
    style: function (feature) {
      // 根据要素feature的属性设置样式
      return {
        color: color, // 线条或者边框的颜色
        weight: 4, // 线条或者边框的宽度,像素单位
        // opacity: 0.5, // 线条或者边框的透明度
        // fillColor: "#ff7800", // 多边形的填充颜色
        fillOpacity: 0.3, // 多边形的填充透明度
        // dashArry: [5, 10], // 虚线的模式,5像素的视线后跟10像素的间隙
        // lineCap: "round", // 线段末端的样式，可以是 'butt'（默认）、'round' 或 'square'
        // lineJoin: "round", // 线段连接处的样式，可以是 'miter'（默认）、'round' 或'bevel'
        // clickable: true, // 是否允许点击该几何对象，默认为true响应鼠标事件
      };
    },
  }).addTo(map);

  emit("geojson-group", { name: text, group }); // 绘制geojson后触发并携带绘制的图层数据

  // 如果需要，将地图的视图调整为包含绘制的几何对象
  if (flyToBounds) {
    map.flyToBounds(group.getBounds());
  }

  markerItem[text + "Group"] = group; // 将绘制的图层定义名称添加到markerItem对象中,方便后续的删除
  console.log(markerItem, "markerItem");
};

//调查表查看详情定位
const mapdlocation = (data: any) => {
  console.log(data, "默认点位");
  // setView(one,two,three) 设置地图的中心位置和缩放级别并平滑过渡,one纬度经度的中心点坐标，two缩放级别，three动画效果
  map.setView(data, 12, {
    easeLinearity: 0.5, // 动画的加速曲线，值范围为0到1，值越大动画越平滑,默认0.25
    duration: 0.8, // 动画的总持续时间（单位：秒）
    animate: true, // 是否启用动画过渡效果
    // pan：{ // 控制地图平移行为的选项
    //  animate:true, // 启用动画效果
    //  duration: 0.8, // 动画的总持续时间
    // }
    // zoom:{ // 控制地图缩放行为的选项
    //  animate:true, // 启用动画效果
    //  duration: 0.8, // 动画的总持续时间
    // }
  });
};


// 获取当前地图上绘制的geojson文件内容
const getgetGeojson = () => {
  if (drawLayerGrounp) {
    return drawLayerGrounp.toGeoJSON();
  } else {
    return "";
  }
};


onMounted(() => {
  // 页面渲染时，设置地图显示区域的缩放比例
  zoom.value = 1 / document.documentElement.style.zoom;
  window.addEventListener("resize", () => {
    zoom.value = 1 / document.documentElement.style.zoom;
  });

  nextTick(() => {
    initMap(); // 初始化图层
  });
});

onUnmounted(() => {
  // 页面注销时地图存在则销毁地图
  map && map.remove();
});

</script>

<style lang="scss" scoped>
.map {
  width: 100%;
  height: 100%;
}

.btnbox {
  position: absolute;
  margin: 10px 0 0 10px;

  .btn {
    width: 100%;
    height: 20%;
    margin-top: 5px;
    background: white;
    border-radius: 10px;
    text-align: center;
    line-height: 35px;
    cursor: pointer;
  }
}
</style>

